<template>
  <div
    class="treeComm"
    style="border-right: 0px solid #ebeef1"
    :style="commpStyle"
    @contextmenu.prevent="balnkClick"
  >
    <!-- 顶部按钮区 -->
    <div class="treeButton" v-if="treeTop">
      <el-button type="success" plain icon="el-icon-tianjia" @click="leftButton"
        >新建工程</el-button
      >
      <el-button type="success" plain icon="el-icon-guanli" @click="rightButton"
        >打开工程</el-button
      >
    </div>
    <!-- 查询内容区 -->
    <div class="find">
      <el-input
        v-if="switchValueShow"
        placeholder="请输入关键字"
        prefix-icon="el-icon-search"
        v-model="filterText"
      >
      </el-input>
    </div>
    <!-- 树本身 -->
    <div class="box-card">
      <el-scrollbar>
        <el-tree
          class="filter-tree"
          :highlight-current="true"
          :data="treeData"
          :props="dataProps"
          :default-expand-all="true"
          :filter-node-method="filterNode"
          :show-checkbox="multiple"
          :check-on-click-node="true"
          :node-key="dataProps.value"
          :current-node-key="dataProps.value"
          @node-click="handleNodeClick"
          @node-contextmenu="rightClick"
          @check-change="handlNodeCheckChange"
          @check="handlNodelCheck"
          :default-checked-keys="defaultCheckedKeys"
          :default-expanded-keys="defaultExpandedKeys"
          ref="tree"
        >
          <span class="custom-tree-node" slot-scope="{ node, data }">
            <svg class="iconfont" aria-hidden="true" v-if="data.icon">
              <use :xlink:href="getIconFont(data)"></use>
            </svg>
            {{ node.label }}
          </span>
        </el-tree>
      </el-scrollbar>
      <!--    鼠标右键菜单栏-->
      <div class="dev-type-main-left">
        <div v-if="showRightMenu" id="menu" class="right-menu">
          <!--          <el-row-->
          <!--            :key="'rowIndex_' + rowIndex"-->
          <!--            v-for="rowIndex in Number(rightMenu.row)"-->
          <!--          >-->
          <!--            <el-col-->
          <!--              :key="rowIndex + '_colIndex_' + colIndex"-->
          <!--              v-for="colIndex in Number(rightMenu.col)"-->
          <!--              :span="24 / Number(rightMenu.col)"-->
          <!--              :style="getComponentStyle(rightMenu.renders, rowIndex, colIndex)"-->
          <!--            >-->
          <!--              <component-->
          <!--                :is="getSubComponent(rightMenu.renders, rowIndex, colIndex)"-->
          <!--                v-bind="-->
          <!--                  getSubComponentParams(rightMenu.renders, rowIndex, colIndex)-->
          <!--                "-->
          <!--                v-on="-->
          <!--                  getSubComponentEvent(rightMenu.renders, rowIndex, colIndex)-->
          <!--                "-->
          <!--                :multiple="false"-->
          <!--              >-->
          <!--                <span-->
          <!--                  v-html="-->
          <!--                    getSubComponentHtml(rightMenu.renders, rowIndex, colIndex)-->
          <!--                  "-->
          <!--                ></span>-->
          <!--              </component>-->
          <!--            </el-col>-->
          <!--          </el-row>-->
          <div
            class="resizableRow"
            :key="'rowIndex_' + rowIndex"
            v-for="rowIndex in Number(rightMenu.row)"
          >
            <div class="resizableRowContent">
              <div
                class="resizableCol"
                :key="rowIndex + '_colIndex_' + colIndex"
                v-for="colIndex in Number(rightMenu.col)"
                :style="getComponentStyle(rightMenu.render, rowIndex, colIndex)"
              >
                <div class="resizableColContent">
                  <component
                    :is="getSubComponent(rightMenu.render, rowIndex, colIndex)"
                    v-bind="
                      getSubComponentParams(
                        rightMenu.render,
                        rowIndex,
                        colIndex
                      )
                    "
                    v-on="
                      getSubComponentEvent(rightMenu.render, rowIndex, colIndex)
                    "
                    :multiple="false"
                  >
                    <span
                      v-html="
                        getSubComponentHtml(
                          rightMenu.render,
                          rowIndex,
                          colIndex
                        )
                      "
                    ></span>
                  </component>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--   空白菜单栏-->
    <div class="dev-type-main-left">
      <div v-if="showBlankMenu" id="menuBlank" class="blank-menu">
        <!--        <el-row-->
        <!--          :key="'rowIndex_' + rowIndex"-->
        <!--          v-for="rowIndex in Number(blankRender.row)"-->
        <!--        >-->
        <!--          <el-col-->
        <!--            :key="rowIndex + '_colIndex_' + colIndex"-->
        <!--            v-for="colIndex in Number(blankRender.col)"-->
        <!--            :span="24 / Number(blankRender.col)"-->
        <!--            :style="getComponentStyle(blankRender.render, rowIndex, colIndex)"-->
        <!--          >-->
        <!--            <component-->
        <!--              :is="getSubComponent(blankRender.render, rowIndex, colIndex)"-->
        <!--              v-bind="-->
        <!--                getSubComponentParams(blankRender.render, rowIndex, colIndex)-->
        <!--              "-->
        <!--              v-on="-->
        <!--                getSubComponentEvent(blankRender.render, rowIndex, colIndex)-->
        <!--              "-->
        <!--              :multiple="false"-->
        <!--            >-->
        <!--              <span-->
        <!--                v-html="-->
        <!--                  getSubComponentHtml(blankRender.render, rowIndex, colIndex)-->
        <!--                "-->
        <!--              ></span>-->
        <!--            </component>-->
        <!--          </el-col>-->
        <!--        </el-row>-->
        <div
          class="resizableRow"
          :key="'rowIndex_' + rowIndex"
          v-for="rowIndex in Number(blankRender.row)"
        >
          <div class="resizableRowContent">
            <div
              class="resizableCol"
              :key="rowIndex + '_colIndex_' + colIndex"
              v-for="colIndex in Number(blankRender.col)"
              :style="getComponentStyle(blankRender.render, rowIndex, colIndex)"
            >
              <div class="resizableColContent">
                <component
                  :is="getSubComponent(blankRender.render, rowIndex, colIndex)"
                  v-bind="
                    getSubComponentParams(
                      blankRender.render,
                      rowIndex,
                      colIndex
                    )
                  "
                  v-on="
                    getSubComponentEvent(blankRender.render, rowIndex, colIndex)
                  "
                  :multiple="false"
                >
                  <span
                    v-html="
                      getSubComponentHtml(
                        blankRender.render,
                        rowIndex,
                        colIndex
                      )
                    "
                  ></span>
                </component>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import baseComp from "./baseComp";

export default {
  name: "commonTree",
  model: {
      prop: 'treeValue',
      event: 'treeChange'
  },
  props: [
    "dicData",
    "switchValue",
    "multiple",
    "event",
    "dicUrl",
    "dicMethod",
    "dicQueryConfig",
    "dicFormatter",
    "dataProps",
    "rightMenu",
    "blankRender",
    "nodeRConf",
    "blankRConf",
    "treeTop",
    "treeValue"
  ],
  extends: baseComp,
  watch: {
    switchValue: {
      handler(val) {},
      deep: true,
      immediate: true,
    },
    dataProps: {
      handler(val) {},
      deep: true,
      immediate: true,
    },
    filterText(val) {
      this.$refs.tree.filter(val);
    },
    dicData: {
      handler(val) {
        // this.treeData = val;
      },
      deep: true,
      immediate: true,
    },
    dicUrl: {},
    dicMethod: {},
    dicQueryConfig: [],
    rightMenu: {
      handler(val) {
        // this.treeData = val;
      },
      deep: true,
      immediate: true,
    },
    treeTop: {
      handler(val) {},
      deep: true,
      immediate: true,
    },
    treeValue: {
      handler(val) {
        if(val){
          if (!(val instanceof Array)){
            setTimeout(()=>{
              this.$refs.tree.setCurrentKey(val);
            },1000);
            // this.$nextTick(()=>{
            //   this.$set(this,'defaultCheckedKeys',[val]);
            //   this.$set(this,'defaultExpandedKeys',[val]);
            // })
          }else{
            this.$nextTick(()=>{
              this.$refs.tree.setCurrentKey(val);
              this.$set(this,'defaultCheckedKeys',val);
              this.$set(this,'defaultExpandedKeys',val);
            })
          }
        }
      },
      deep: true,
      immediate: true,
    }
  },
  mounted() {
    this.getInit();
  },
  data() {
    return {
      switchValueShow: false,
      treeData: [],
      filterText: "",
      showRightMenu: false,
      showBlankMenu: false,
      newRightMenu: [],
      rightClickData: {},
      defaultExpandedKeys: [], //默认展开的key
      defaultCheckedKeys: [] //默认选中的key
    };
  },
  methods: {
    /**
     * 左侧按钮
     */
    leftButton() {
      this.executeEvent("leftButton", this.path, null);
    },
    /**
     * 右侧按钮
     */
    rightButton() {
      this.executeEvent("rightButton", this.path, null);
    },
    /**
     *
     * @param data 节点icon图标
     */
    getIconFont(data) {
      let icon = "#" + data.icon;
      return icon;
    },
    //树配置
    getInit() {
      this.switchValueShow = this.switchValue;
      let params = {};
      this.dicQueryConfig.forEach((item) => {
        params[item.key] = item.value;
      });
      // 请求重置
      this.executeEvent("requestReset", this.path, params);
      this.$myAxios.request(this.dicMethod, this.dicUrl, params).then((res) => {
        let data = eval(this.dicFormatter)(res);
        this.$set(this, "treeData", data);
        this.executeEvent("requestEndt", this.path, data);
      });
      this.closeRightMenu();
      this.closeBlankMenu();
    },
    /**
     *
     * @param value 过滤值
     * @param data 过滤需要传入的数据集合
     */
    filterNode(value, data) {
      if (!value) {return true;}
      let label = data[this.dataProps.label];
      if(!label){return true;}
      return label.indexOf(value) !== -1;
    },
    /**
     *
     * @param data 节点checkbox点击节点
     * @param nodeCheck 点击节点树目前的选中状态对象包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
     */
    handlNodelCheck(data, nodeCheck){
      // let checkData = this.$refs.tree.getCheckedNodes();
      if (this.multiple){
        let checkData = this.$refs.tree.getCheckedKeys();
        this.$emit('treeChange', checkData);
      }
    },
    /**
     *
     * @param node 被点击的节点对象
     * @param check 被点击节点是否选中状态
     * @param chilCheck 节点的子树中是否有被选中的节点
     */
    handlNodeCheckChange(node, check, chilCheck){
      //对外提交组件选中的值
    },

    /**
     *
     * @param data 点击当前节点所对应的对象
     * @param Node 节点对应的 Node
     * @param nodeEl 节点组件本身，对应html元素
     */
    handleNodeClick(data, Node, nodeEl) {
      if (data) {
        this.executeEvent("constraintCilck", this.path, data);
        // this.$emit('change', data);
      } else {
        this.executeEvent("selectTree", this.path, data);
      }
    },
    /**
     *
     * @param event 右击事件对象
     * @param data 点击当前节点所对应的对象
     * @param node 节点对应的 Node
     * @param nodeEl 节点组件本身，对应html元素
     */
    rightClick(event, data, node, nodeEl) {
      this.rightClickData = data;
      this.showBlankMenu = false;
      this.showRightMenu = false; // 先把模态框关死，目的是：第二次或者第n次右键鼠标的时候 它默认的是true
      // 判断当前的对应属性值是否存在 当节点开启或者是属性值为*打开
      if (this.nodeRConf) {
        // let nodeRConf = this.rightMenu.nodeRConf;
        //加载右击菜单数据
        let render = this.rightMenu.render;
        let resRender = [];
        if (render.length > 0) {
          for (let i = 0; i < render.length; i++) {
            if (render[i].lableValue === data.type) {
              resRender.push(render[i]);
            }
          }
          this.rightMenu.renders = null;
          this.rightMenu.renders = resRender;
          if (resRender.length === 0) {
            this.showRightMenu = false;
          } else {
            this.showRightMenu = true;
          }
        } else {
          this.showRightMenu = true;
        }
        this.$nextTick(() => {
          let menu = document.querySelector(".right-menu");
          if (!menu) {
            return;
          }
          menu.style.left = event.layerX + "px";
          menu.style.top = event.layerY + "px";
          menu.style.width = this.rightMenu.menuWidth;
          menu.style.height = this.rightMenu.menuHeight;
          document.addEventListener("click", this.closeRightMenu);
        });
      } else {
        this.showRightMenu = false;
      }
    },
    /**
     *
     * @param event 点击事件
     * @param data
     * @param node
     * @param obj
     */
    balnkClick(event, data, node, obj) {
      this.showRightMenu = false;
      this.showBlankMenu = false; // 先把模态框关死，目的是：第二次或者第n次右键鼠标的时候 它默认的是true
      if (this.blankRConf) {
        this.showBlankMenu = true;
        this.$nextTick(() => {
          let menu = document.querySelector(".blank-menu");
          menu.style.left = event.layerX + "px";
          menu.style.top = event.layerY + "px";
          menu.style.width = this.blankRender.menuWidth;
          menu.style.height = this.blankRender.menuHeight;
          document.addEventListener("click", this.closeBlankMenu);
        });
      } else {
        this.showBlankMenu = false;
      }
    },
    changeRightMenu(val) {
      let menu = document.querySelector(".right-menu");
      menu.style.width = val.menuWidth;
      menu.style.height = val.menuHeight;
      menu.style.height = val.menuHeight;
    },
    closeRightMenu() {
      this.showRightMenu = false;
      // 及时关掉鼠标监听事件
      document.removeEventListener("click", this.closeRightMenu);
      document.removeEventListener("click", this.closeBlankMenu);
    },
    closeBlankMenu() {
      this.showBlankMenu = false;
      // 及时关掉鼠标监听事件
      document.removeEventListener("click", this.closeRightMenu);
      document.removeEventListener("click", this.closeBlankMenu);
    },
    //布局组件渲染配置
    getSubComponent(dataList, rowIndex, colIndex) {
      let component = dataList.find(
        (item) =>
          (item.rowNum == "*" || item.rowNum == rowIndex) &&
          item.colNum == colIndex
      );
      return this.getComponent(component);
    },
    /**
     * 获取组件渲染参数
     * @param rowIndex  this.toolbar.custom.render
     * @param colIndex
     * @returns {string|*}
     */
    getSubComponentParams(dataList, rowIndex, colIndex) {
      let component = dataList.find(
        (item) =>
          (item.rowNum == "*" || item.rowNum == rowIndex) &&
          item.colNum == colIndex
      );
      return this.getComponentParams(component);
    },
    /**
     * 获取组件事件
     */
    getSubComponentEvent(dataList, rowIndex, colIndex) {
      let component = dataList.find(
        (item) =>
          (item.rowNum == "*" || item.rowNum == rowIndex) &&
          item.colNum == colIndex
      );
      return this.getComponentEvent(component);
    },
    /**
     * 获取组件html
     */
    getSubComponentHtml(dataList, rowIndex, colIndex) {
      let component = dataList.find(
        (item) =>
          (item.rowNum == "*" || item.rowNum == rowIndex) &&
          item.colNum == colIndex
      );
      return this.getComponentHtml(component);
    },
    /**
     * 获取组件样式 this.toolbar.custom.render
     * @param rowIndex
     * @param colIndex
     * @returns {{width: *, height: *}}
     */
    getComponentStyle(dataList, rowIndex, colIndex) {
      let component = dataList.find(
        (item) =>
          (item.rowNum == "*" || item.rowNum == rowIndex) &&
          item.colNum == colIndex
      );
      if (component) {
        return {
          width: component.width + "px",
          height: component.height + "px",
        };
      }
    },
  },
};
</script>
<style lang='less' scoped>
.treeComm {
  width: 100%;
  height: 100%;
  .find {
    width: 100%;
    background-color: white;
  }

.find /deep/ .el-input {
  margin: 18px 0 10px 6px;
  width: 96%;
}
  .find /deep/ .el-input {
    margin: 18px 0 10px 6px;
    width: 96%;
  }

  .find /deep/ .el-input__inner {
    // width: 202px;
    height: 32px;
    border: 1px solid #cccccc;
  }

  .find /deep/ .el-input__icon {
    line-height: 32px;
  }
  .treeButton {
    width: 100%;
    height: 60px;
    .el-button {
      margin: 10px;
    }
  }
  .box-card {
    font-family: Source Han Sans Medium !important;
    font-weight: 420;
    font-size: 14px;
    //height: calc(100vh - 90px);
    height: calc(100% - 60px);
    overflow-y: auto;
    .el-scrollbar {
      width: 100%;
      height: 100%;
    }
    .filter-tree {
      // height: 280px;

      /deep/ .el-tree-node.is-current > .el-tree-node__content {
        background-color: #f8f8f8 !important;
      }
    }
  }

  .dev-type-main-left {
    overflow: auto;
    //padding: 10px;

    .right-menu {
      z-index: 1;
      position: absolute;
      height: 100px;
      width: 100px;
      position: absolute;
      border-radius: 3px;
      border: 1px solid #ccc;
      background-color: white;

      .menu-item {
        //display: block;
        line-height: 20px;
        text-align: left;
        margin-top: 10px;
        font-size: 14px;
        color: #606266;
      }
    }

    .blank-menu {
      z-index: 1;
      position: absolute;
      height: 100px;
      width: 100px;
      position: absolute;
      border-radius: 3px;
      border: 1px solid #ccc;
      background-color: white;

      .menu-item {
        //display: block;
        line-height: 20px;
        text-align: left;
        margin-top: 10px;
        font-size: 14px;
        color: #606266;
      }
    }
  }
}
</style>
